package com.project.core.util;

import com.alibaba.fastjson2.JSON;
import com.common.common.Code;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 通用工具类
 *
 * @version 1.0
 * @since 1.0
 */
public class CommonUtil {

    //空行、换行分隔符
    public static final String SEPARATOR = "\r\n";

    /**
     * UUID去掉-
     *
     * @return uuid
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 获取md5加密的字符串
     *
     * @param content 字符串
     */
    public static String generateMD5Hash(String content) {
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("MD5");
            byte[] hashedBytes = digest.digest(content.getBytes(StandardCharsets.UTF_8));
            StringBuilder stringBuffer = new StringBuilder();
            for (byte hashedByte : hashedBytes) {
                stringBuffer.append(Integer.toString((hashedByte & 0xff) + 0x100, 16)
                        .substring(1));
            }
            return stringBuffer.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取md5加密的字符串
     *
     * @param bytes 字符串
     */
    public static String generateMD5Hash(byte[] bytes) {
        StringBuilder stringBuffer = new StringBuilder();
        for (byte aByte : bytes) {
            stringBuffer.append(Integer.toString((aByte & 0xff) + 0x100, 16)
                    .substring(1));
        }
        return stringBuffer.toString();
    }

    /**
     * 获取枚举类的name、desc对象List
     *
     * @param clz 枚举所在的class文件
     * @return 枚举类列表数据
     */
    public static List<Code> getEnumList(Class<?> clz) {
        if (!clz.isEnum()) {
            throw new RuntimeException();
        }
        List<Code> enumList = new ArrayList<>();
        try {
            // 1.得到所有枚举常量
            Object[] objects = clz.getEnumConstants();
            Method value = clz.getMethod("getDesc");
            Method code = clz.getMethod("name");
            for (Object obj : objects) {
                // 2.调用对应方法，得到枚举常量中字段的值
                enumList.add(new Code((String) code.invoke(obj), (String) value.invoke(obj)));
            }
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        return enumList;
    }

    /**
     * 通过枚举值获取当前枚举值的枚举对象
     *
     * @param name 枚举值
     * @param clz  枚举class
     * @return 返回一个枚举对象
     */
    public static Object getEnumObject(String name, Class<?> clz) {
        if (!clz.isEnum()) {
            throw new RuntimeException();
        }
        try {
            // 1.得到所有枚举常量
            Object[] objects = clz.getEnumConstants();
            Method code = clz.getMethod("name");
            for (Object obj : objects) {
                if (name.equals(code.invoke(obj))) {
                    return obj;
                }
            }
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 当字符串的最后一个字符等于lastStr时，将之去除
     *
     * @param string  需要调整的字符串
     * @param lastStr 最后一个字符
     */
    public static String replaceLastStr(String string, String lastStr) {
        int stringLength = string.length();
        int lastStrIndex = string.lastIndexOf(lastStr);
        if (stringLength - 1 == lastStrIndex) {
            return string.substring(0, stringLength - 1);
        } else {
            return string;
        }
    }

    /**
     * 当字符串的最后一个字符等于lastStr时，返回ture
     *
     * @param string  需要判断的字符串
     * @param lastStr 最后一个字符
     */
    public static boolean JudgmentLastStr(String string, String lastStr) {
        int stringLength = string.length();
        int lastStrIndex = string.lastIndexOf(lastStr);
        return stringLength - 1 == lastStrIndex;
    }

    /**
     * String转List<String>
     *
     * @param str str1,str2,str3
     */
    public static List<String> string2List(String str) {
        List<String> listStr = new ArrayList<>();
        if (!StringUtils.isBlank(str)) {
            if (str.contains(",")) {
                listStr = Arrays.asList(str.split(","));
            } else {
                listStr.add(str);
            }
        }
        return listStr;
    }

    /**
     * 生成业务流水号
     *
     * @param simpleName 业务简称
     * @return 返回 业务简称+yyyyMMddHHmmss+3位随机数的编码，例如SP20190527183410001
     */
    public static String createSerialNumber(String simpleName) {
        DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String currentTimeStr = DATETIME_FORMAT.format(LocalDateTime.now());
        return simpleName + currentTimeStr + RandomStringUtils.randomNumeric(3);
    }

    /**
     * 将map转换为bean对象
     *
     * @param map   map对象
     * @param clazz bean对象class
     * @return bean对象
     */
    public static <T> T mapToBean(Map<?, ?> map, Class<T> clazz) {
        try {
            return JSON.parseObject(JSON.toJSONString(map), clazz);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将bean对象转换为map
     *
     * @param bean bean对象
     * @return map对象
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        return (Map<String, Object>) JSON.toJSON(bean);
    }
}
